home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et3_0-a1.lha / et3 / src / WindowPort.C < prev    next >
C/C++ Source or Header  |  1992-08-26  |  9KB  |  476 lines

  1. #ifdef __GNUG__
  2. #pragma implementation
  3. #endif
  4.  
  5. #include "WindowPort.h"
  6.  
  7. #include "Class.h"
  8. #include "Error.h"
  9. #include "System.h"
  10. #include "WindowSystem.h"
  11. #include "Math.h"
  12. #include "Storage.h"
  13. #include "String.h"
  14. #include "Window.h"
  15. #include "OrdColl.h"
  16. #include "Region.h"
  17. #include "WindowColorMap.h"
  18.  
  19.  
  20. //---- WindowPort --------------------------------------------------------------
  21.  
  22. NewMetaImpl(WindowPort, Port, (TP(win), TE(state), T(lastpos), T(portrect), TP(wcmap)));
  23.  
  24. WindowPort::WindowPort(Window *bw, WindowType, GrCursor curs)
  25. {
  26.     win= bw;
  27.     overlay= FALSE;
  28.     state= eWsHidden;
  29.     cursor= curs;
  30.     hascolor= gColor;
  31.     inval= 0;
  32.     wcmap= 0;
  33.     
  34.     havepushbacktoken= FALSE;
  35.     if (gWindowSystem)
  36.     gWindowSystem->AddWindow(this);
  37. }
  38.  
  39. WindowPort::~WindowPort()
  40. {
  41.     if (gWindowSystem)
  42.     gWindowSystem->RemoveWindow(this);
  43.     if (state != eWsClosed) {
  44.     state= eWsClosed;
  45.     ExitLoop();
  46.     SafeDelete(inval);
  47.     }
  48.     if (wcmap) {
  49.     wcmap->Unref();
  50.     wcmap= 0;
  51.     }
  52. }
  53.  
  54. //---- Callbacks ---------------------------------------------------------------
  55.  
  56. void WindowPort::OpenNotify(Rectangle r)
  57. {
  58.     portrect= r;
  59.     state= eWsShown;
  60.     if (win)
  61.     win->OpenNotify(r.extent);
  62. }
  63.  
  64. void WindowPort::CloseNotify()
  65. {
  66.     SafeDelete(inval);
  67.     state= eWsHidden;
  68.     ExitLoop();
  69.     if (win)
  70.     win->CloseNotify();
  71.     gSystem->InnerLoop();
  72. }
  73.  
  74. void WindowPort::InputNotify(Token *t)
  75. {
  76.     if (state != eWsShown)
  77.     return;
  78.     
  79.     if (t->Code != eEvtNone && t->Code != eEvtIdle) {
  80.     lastpos= t->Pos;
  81.     WindowSystem::lasttime= t->At;
  82.     } else if (t->Code == eEvtNone) {
  83.     t->Flags= 0;
  84.     t->Pos= lastpos;
  85.     t->At= WindowSystem::lasttime;
  86.     }
  87.     
  88.     // emergency exit :-)
  89.     if (t->IsKey() && t->Flags == (eFlgShiftKey|eFlgCntlKey|eFlgMetaKey)
  90.                          && t->MapToAscii() == 'u')
  91.     gSystem->Exit(1, FALSE);
  92.     
  93.     if (WindowSystem::grabport && (WindowSystem::grabport != this)) {
  94.     switch (t->Code) {
  95.     case eEvtIdle:
  96.     case eEvtNone:
  97.     case eEvtLocMove:
  98.     case eEvtLocMoveBut:
  99.     case eEvtLocStill:
  100.         // ignore events
  101.         return;
  102.     case eEvtEnter:
  103.     case eEvtExit:
  104.         break;
  105.     default:
  106.         if (t->IsKey() || t->IsFunctionKey() || t->IsCursorKey())
  107.         WindowSystem::grabport->InputNotify(t);
  108.         else
  109.         WindowSystem::grabport->Bell(50);
  110.         return;
  111.     }  
  112.     }
  113.     if (t->IsMouseButton()) {
  114.     if (WindowSystem::lastClick.DoubleClick(*t))
  115.         WindowSystem::Clicks++;
  116.     else
  117.         WindowSystem::Clicks= 1;
  118.     WindowSystem::lastClick= *t;
  119.     }
  120.     if (win)
  121.     win->InputNotify(t);
  122. }
  123.  
  124. //---- Invalidation ------------------------------------------------------------
  125.  
  126. void WindowPort::InvalidateRect(const Rectangle &r, bool update)
  127. {
  128.     if (state == eWsShown) {
  129.     if (inval == 0)
  130.         inval= new Region;
  131.     inval->Merge(r);
  132.     }
  133.     if (update)
  134.     gWindowSystem->Update();
  135. }
  136.  
  137. void WindowPort::DevUpdate()
  138. {
  139.     if (inval == 0 || inval->size <= 0)
  140.     return;
  141.     Region *old= inval;
  142.     inval= 0;
  143.     Rectangle *ir;
  144.     
  145.     for (int i= 0; ir= old->GetAt(i); i++) {
  146.     UpdateRect(*ir);
  147.     GiveHint(eHintUnbatch, 0, 0);
  148.     }
  149.     delete old;
  150. }
  151.  
  152. void WindowPort::UpdateRect(Rectangle &r)
  153. {
  154.     if (win) {
  155.     Port *oldport= GrGetPort();
  156.     GrSetPort(this);
  157.     InitClip();
  158.     Clip(Inter(win->contentRect, r));
  159.     SetPenNormal();
  160.     SetInk(ePatBlack);
  161.     GiveHint(eHintBatch, sizeof(Rectangle), &r);
  162.     win->DrawAll(r, FALSE);
  163.     FlushMyText();
  164.     GrSetPort(oldport);
  165.     }
  166. }
  167.  
  168. void WindowPort::FlushColorMap()
  169. {
  170.     if (wcmap)
  171.     wcmap->Install(this);
  172. }
  173.  
  174. void WindowPort::DevSetColor(RGBColor *cp)
  175. {
  176.     u_long id= cp->GetId();
  177.     if (cp->TestFlag(eInkChanged)) {
  178.     if (cp->GetPrec() == 255) {
  179.         if (wcmap == WindowSystem::wcmap) {
  180.         wcmap= wcmap->MakeCopy(WindowSystem::wcmap);
  181.         wcmap->Ref();
  182.         }
  183.         id= wcmap->AllocateAndSetCell(id, cp->GetRGB(), this);
  184.     } else
  185.         id= wcmap->RGB2Index(cp->GetRGB());
  186.     cp->SetId(id);
  187.     cp->ResetFlag(eInkChanged);
  188.     }
  189.     DevSetColor2(id);
  190. }
  191.  
  192. //---- cursor stuff ------------------------------------------------------------
  193.  
  194. GrCursor WindowPort::SetCursor(GrCursor c)
  195. {
  196.     if (c != cursor && c >= eCrsNone && c <= eCrsUpDownArrow) {
  197.     GrCursor oldc= cursor;
  198.     cursor= c;
  199.     DevSetCursor(c);
  200.     return oldc;
  201.     }
  202.     return c;
  203. }
  204.  
  205. GrCursor WindowPort::GetCursor()
  206. {
  207.     return cursor;
  208. }
  209.  
  210. GrCursor WindowPort::SetWaitCursor(unsigned int, GrCursor c)
  211. {
  212.     c= SetCursor(c);
  213.     GiveHint(eHintWinBusy, 0, 0);
  214.     return c;
  215. }
  216.  
  217. //---- input handling ----------------------------------------------------------
  218.  
  219. void WindowPort::GetEvent(Token *t, int timeout, bool overread)
  220. {
  221.     if (havepushbacktoken) {
  222.     *t= pushbacktoken;
  223.     havepushbacktoken= FALSE;
  224.     } else
  225.     DevGetEvent(t, timeout, overread);
  226.     
  227.     if (t->Code != eEvtNone && t->Code != eEvtIdle) {
  228.     lastpos= t->Pos;
  229.     WindowSystem::lasttime= t->At;
  230.     } else if (t->Code == eEvtNone) {
  231.     t->Pos= lastpos;
  232.     t->At= WindowSystem::lasttime;
  233.     }
  234. };
  235.  
  236. void WindowPort::PushEvent(Token t)
  237. {
  238.     if (t.Code != eEvtNone) {
  239.     pushbacktoken= t;
  240.     havepushbacktoken= TRUE;
  241.     }
  242. }
  243.  
  244. //---- window management -------------------------------------------------------
  245.  
  246. void WindowPort::Hide()
  247. {
  248.     if (state == eWsShown) {
  249.     FlushAnyText();
  250.     DevHide();
  251.     }
  252. };
  253.  
  254. Point showdelta;
  255.  
  256. void WindowPort::Show(WindowPort *father, Rectangle r, bool block)
  257. {
  258.     Point delta;
  259.     Rectangle rr= r;
  260.     
  261.     if (state == eWsShown)
  262.     return;
  263.     
  264.     SafeDelete(inval);
  265.     
  266.     FlushAnyText();
  267.  
  268.     if (father)
  269.     rr.origin+= father->GetRect().origin;
  270.     else if (r.origin == gPoint_1)
  271.     rr.origin= Half(WindowSystem::screenRect.extent - r.extent);
  272.     delta= rr.AmountToTranslateWithin(WindowSystem::screenRect);
  273.     rr.origin+= delta;
  274.     
  275.     DevShow(father, rr);
  276.     showdelta= delta;
  277.     //if (delta != gPoint0)
  278.     //    MoveMousePos(delta);
  279.     if (block) {
  280.     GrabLoop();
  281.     }
  282. };
  283.  
  284. void WindowPort::Poll(int timeout)
  285. {
  286.     WindowPort *oldgrabport= WindowSystem::grabport;
  287.     WindowSystem::grabport= this;
  288.     gSystem->InnerLoop(timeout);
  289.     WindowSystem::grabport= oldgrabport;
  290. }
  291.  
  292. void WindowPort::GrabLoop()
  293. {
  294.     exitloop= FALSE;
  295.     WindowPort *oldgrabport= WindowSystem::grabport;
  296.     WindowSystem::grabport= this;
  297.     do 
  298.     gSystem->InnerLoop();
  299.     while (! exitloop);
  300.     WindowSystem::grabport= oldgrabport;
  301. }
  302.  
  303. void WindowPort::Iconize()
  304. {
  305.     DevIconize();
  306. }
  307.  
  308. void WindowPort::Grab(bool g, bool fs)
  309. {
  310.     if (fs) {
  311.     FlushAnyText();
  312.     WindowSystem::fullscreen= g;
  313.     }
  314.     DevGrab(g, fs);
  315. }
  316.  
  317. void WindowPort::DevSetTitle(char*)
  318. {
  319. }
  320.  
  321. //---- graphic functions -------------------------------------------------------
  322.  
  323. void WindowPort::Scroll(Point delta)
  324. {
  325.     Rectangle r1, rl[4], r(cliprect), oldclip= cliprect;
  326.     register int i, n;
  327.     bool doscroll, batchopen= FALSE;
  328.     
  329.     FlushMyText();
  330.     r1= r + delta;
  331.     doscroll= r.Clip(r1);
  332.     
  333.     n= Difference(rl, cliprect, r1);
  334.     if (0 && n == 1 && WindowSystem::batch && !overlay) {
  335.     UpdateRect(rl[0]);
  336.     batchopen= TRUE;
  337.     } else {
  338.     for (i= 0; i < n; i++)
  339.         InvalidateRect(rl[i]);
  340.     }
  341.     if (r.Clip(r1)) {
  342.     if (batchopen)
  343.         DevClip(oldclip);
  344.     DevScrollRect(r, delta);
  345.     }
  346.     if (batchopen)
  347.     GiveHint(eHintUnbatch, 0, 0);
  348.     DevUpdate();
  349. }
  350.  
  351. bool WindowPort::DevImageCacheBegin(ImageCache *bb, Rectangle r)
  352. {
  353.     if (WindowSystem::batch) {
  354.     if (scale & 2) {
  355.         DevClip(cliprect);
  356.         scale&= ~2;
  357.     }
  358.     FlushMyText();
  359.     r.origin += origin;
  360.     if (r.Clip(cliprect)) {
  361.         r.origin -= origin;
  362.         bb->r= r;
  363.         if (!bb->valid || !bb->vr.ContainsRect(r)) {
  364.         bb->vr= r;
  365.         if (bb->b == 0)
  366.             bb->b= new Bitmap(r.extent, gDepth);
  367.         return TRUE;
  368.         }
  369.     }
  370.     r.origin += origin;
  371.     batchInfo bi;
  372.     bi.b= bb->b->GetDevBitmap();
  373.     bi.r= r;
  374.     bi.p= bb->r.origin - bb->vr.origin;
  375.     DevGiveHint(eHintCacheStart, 0, &bi);
  376.     return FALSE;
  377.     }
  378.     return TRUE;
  379. }
  380.  
  381. void WindowPort::DevImageCacheEnd(ImageCache *bb)
  382. {
  383.     if (WindowSystem::batch) {
  384.     if (scale & 2) {
  385.         DevClip(cliprect);
  386.         scale&= ~2;
  387.     }
  388.     batchInfo bi;
  389.     bi.r= bb->vr;
  390.     bi.r.origin += origin;
  391.     if (bb->b == 0)
  392.         bb->b= new Bitmap(bi.r.extent, gDepth);
  393.     bi.b= bb->b->GetDevBitmap();
  394.     DevGiveHint(eHintCacheEnd, 0, &bi);
  395.     bb->valid= TRUE;
  396.     }
  397. }
  398.  
  399. //---- abstract methods --------------------------------------------------------
  400.  
  401. void WindowPort::DevSetCursor(GrCursor)
  402. {
  403.     AbstractMethod("DevSetCursor");
  404. }
  405.  
  406. void WindowPort::DevScrollRect(Rectangle, Point)
  407. {
  408.     AbstractMethod("DevScrollRect");
  409. }
  410.  
  411. void WindowPort::DevHide()
  412. {
  413.     AbstractMethod("DevHide");
  414. }
  415.  
  416. void WindowPort::DevIconize()
  417. {
  418.     AbstractMethod("DevIconize");
  419. }
  420.  
  421. void WindowPort::DevShow(WindowPort*, Rectangle)
  422. {
  423.     AbstractMethod("DevShow");
  424. }
  425.  
  426. void WindowPort::DevGrab(bool, bool)
  427. {
  428.     AbstractMethod("DevGrab");
  429. }
  430.  
  431. void WindowPort::DevFullscreen(bool)
  432. {
  433.     AbstractMethod("DevFullScreen");
  434. }
  435.  
  436. void WindowPort::DevTop(bool)
  437. {
  438.     AbstractMethod("DevTop");
  439. };
  440.  
  441. void WindowPort::DevGetEvent(Token*, int, bool)
  442. {
  443.     AbstractMethod("DevGetEvent");
  444. };
  445.  
  446. void WindowPort::DevSetMousePos(Point, bool)
  447. {
  448.     AbstractMethod("DevSetMousePos");
  449. };
  450.  
  451. void WindowPort::DevSetColor2(u_long)
  452. {
  453.     AbstractMethod("DevSetColor2");
  454. }
  455.  
  456. void WindowPort::DevBell(long duration)
  457. {
  458.     gWindowSystem->DevBell(duration);
  459. }
  460.  
  461. Rectangle WindowPort::DevGetRect()
  462. {
  463.     return portrect;
  464. }
  465.  
  466. void WindowPort::DevSetExtent(Point e)
  467. {
  468.     portrect.extent= e;
  469. }
  470.  
  471. void WindowPort::DevSetOrigin(Point o)
  472. {
  473.     portrect.origin= o;
  474. }
  475.  
  476.